#ifndef MATHEXPRESS_H
#define MATHEXPRESS_H

#include <string>
#include <algorithm>
#include <iostream>

bool isInvalidChar(char c);

/**
 * @brief the class storing a valid math expression 
 * 
 */
class MathExpress
{
private:
    std::string express;

    /**
     * @brief filter the invalid character in the original string 
     * 
     */
    void filter();

public:
    /**
     * @brief Construct a new Math Express object based on a string
     * 
     * @param str 
     */
    MathExpress(const std::string &str);

    /**
     * @brief Destroy the Math Express object
     * 
     */
    ~MathExpress() {}

    /**
    * @brief verify whether 'c' is a invalid char in a math expression 
    * 
    * @param c 
    * @return true 
    * @return false 
    */
    static bool isInvalidChar(char c);

    /**
     * @brief Get the Expression object
     * 
     * @return const std::string& 
     */
    const std::string &getExpression() const { return express; }

    /**
     * @brief print the Math Express
     * 
     * @param out 
     * @param exp 
     * @return std::ostream& 
     */
    friend std::ostream &operator<<(std::ostream &out, const MathExpress &exp);
};

void MathExpress::filter()
{
    //filter all the invalid character
    express.erase(std::remove_if(express.begin(), express.end(), isInvalidChar), express.end());
}

MathExpress::MathExpress(const std::string &str) : express(str)
{
    filter();
}

bool MathExpress::isInvalidChar(char c)
{
    //all the valid characters are in the string 'valid'
    std::string valid = "0.123456789+-*/()";
    return (valid.find(c) == std::string::npos);
}

std::ostream &operator<<(std::ostream &out, const MathExpress &exp)
{
    out << exp.express;
    return out;
}

#endif